import { Button } from "@/components/ui/button"
import React, { Reducer, createContext, memo, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react"
import { produce } from 'immer'

interface Data {
  result: number
}

interface Action {
  type: 'add' | 'minus',
  num: number
}

interface RefProps {
  aaa: () => void
}

const Guang: React.ForwardRefRenderFunction<RefProps> = (props, ref) => {

  const inputRef = useRef<HTMLInputElement>(null)

  useImperativeHandle(ref, () => {
    return {
      aaa() {
        inputRef.current?.focus()
      }
    }
  }, [inputRef])

  return <div>
    <input ref={inputRef}></input>
  </div>
}

const WrapGuang = React.forwardRef(Guang)

const countContext = createContext(111)

function Aaa() {
  console.log('aaa')
  const [count, setCount] = useState(2)

  const bbbCallback = useCallback(() => {

  }, [])

  const count2 = useMemo(() => {
    return count * 10
  }, [count])

  return <div>
    <Button onClick={() => {
      setCount(count + 1)
    }} > +</Button>
    <countContext.Provider value={count2}>
      <MemoBbb callback={bbbCallback} count={count2} ></MemoBbb>
    </countContext.Provider>
  </div>
}

const MemoAaa = memo(Aaa)


function Bbb(props: any) {
  console.log('props', props);
  return <div><Ccc></Ccc></div>
}

const MemoBbb = memo(Bbb)


function Ccc() {
  const count = useContext(countContext)
  return <div>context的值为：{count}</div>
}

const Hooks = () => {
  const [state, setState] = useState(() => {
    const num1 = 1 + 2;
    const num2 = 2 + 3;
    return num1 + num2
  })

  const numRef = useRef<number>(0)

  const [, forceRender] = useState(0)

  const [res, dispatch] = useReducer<Reducer<Data, Action>>(reducer, { result: 0 })

  const ref = useRef<RefProps>(null)

  const add = () => {
    setState(state + 1)
  }

  async function queryData() {
    const data = await new Promise<number>((resolve) => {
      setTimeout(() => {
        resolve(3)
      }, 200)
    })

    return data
  }

  useEffect(() => {
    console.log('effect');
    queryData().then(setState)
    return () => {
      console.log('leave');
    }
  }, [])

  /* 定时器 */
  useLayoutEffect(() => {
    const timer = setTimeout(() => {
      console.log(state)
    }, 1000)

    // state变化之前 先执行
    return () => {
      console.log('clean up')
      clearTimeout(timer)
    }
  }, [state])



  function reducer(state: Data, action: Action) {
    switch (action.type) {
      case 'add':
        return produce(state, (state) => {
          state.result += action.num
        })
      case 'minus':
        return {
          result: state.result - action.num
        }
    }
  }

  return <div>
    <h3>useState</h3>
    <Button onClick={add} >count ++</Button>
    <p>{state}</p>

    <h3>useReducer</h3>
    <div className='flex gap-1'>
      <Button onClick={() => dispatch({ type: 'add', num: 2 })}>加</Button>
      <Button onClick={() => dispatch({ type: 'minus', num: 2 })}>减</Button>
    </div>
    <p>{res.result}</p>

    <h3>useRef</h3>
    <Button onClick={() => {
      numRef.current += 1;
      forceRender(Math.random())
    }}>{numRef.current}</Button>

    <h3>useRef2</h3>
    <Button onClick={() => {
      ref.current?.aaa()
    }}>input focus</Button>
    <p className=" p-1" />
    <WrapGuang ref={ref} />

    <h3>context</h3>
    <MemoAaa />
  </div>
}

export default Hooks